import { Component, ChangeDetectorRef, OnInit, ViewChild, TemplateRef } from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { AfMessageService, AfNavigationService, AfSecurityService, AfUpDownService } from '@core';
import { STChange, STColumn, STComponent } from '@delon/abc/st';
import { ModalHelper } from '@delon/theme';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzContextMenuService, NzDropdownMenuComponent } from 'ng-zorro-antd/dropdown';
import { NzModalService } from 'ng-zorro-antd/modal';
import { NzTreeComponent, NzFormatEmitEvent, NzTreeNode, NzTreeNodeOptions } from 'ng-zorro-antd/tree';
import { NzTreeSelectComponent } from 'ng-zorro-antd/tree-select';
import { AfExcelService, ExcelUploadRecord } from 'src/app/routes/system/excel/af-excel.service';
import { ExcelUploadComponent } from 'src/app/routes/system/excel/upload/excel-upload.component';

import { CodeGenService } from '../../codegen.service';
import { DataSourceSelectComponent } from '../../core/data-source-select/data-source-select.component';
import { LangDBScriptComponent } from '../../lang/db-script/lang-db-script.component';
import { LangJpaScriptComponent } from '../../lang/jpa-script/lang-jpa-script.component';
import { ActionType, LangSourceType } from '../../lang/lang';
import {
  NodeType,
  SourceType,
  DruidDbTypes,
  ColumnForm,
  ConstraintForm,
  DataTypes,
  ConstraintTypes,
  OptType,
  ImportType,
  CONST_COLUMNS,
  FolderNode
} from '../meta-info';

@Component({
  selector: 'app-cg-meta-info',
  templateUrl: './meta-info.component.html',
  styleUrls: ['./meta-info.component.less']
})
export class MetaInfoComponent implements OnInit {
  @ViewChild('nzTreeComponent', { static: false }) nzTreeComponent!: NzTreeComponent;
  @ViewChild('nzTreeSelect', { static: false }) nzTreeSelect!: NzTreeSelectComponent;

  dataTypes = DataTypes;
  constraintTypes = ConstraintTypes;
  nodeTree: any[] = [];
  tmTree: any[] = [];

  currentNodeData: any = this.newFolderNode();
  currentPNodeData: any;
  dbSourceOptions: any[] = [];
  dbSources: any[] | null = null;

  constructor(
    private router: Router,
    private modal: ModalHelper,
    private codegen: CodeGenService,
    private cdr: ChangeDetectorRef,
    private msgSrv: AfMessageService,
    private modalSrv: NzModalService,
    private excelSrv: AfExcelService,
    private updownSrv: AfUpDownService,
    private securitySrv: AfSecurityService,
    private nzContextMenuService: NzContextMenuService
  ) {}

  ngOnInit(): void {
    this.tableInfoForm.controls.tableName.disable();
    this.tableInfoForm.controls.sourceType.disable();
    this.tableInfoForm.controls.sourceName.disable();
    this.getWorkspace();
    this.initDataTypes();
  }

  initDataTypes() {
    this.codegen.getUnifiedDataTpe().subscribe(res => {
      if (res.status) {
        this.dataTypes = res.data;
      }
    });
  }

  newFolderNode(): FolderNode {
    return {
      key: '',
      title: '',
      id: '',
      pid: '0',
      workspaceId: 0,
      type: NodeType.folder,
      name: '',
      remark: ''
    };
  }

  isLoading = false;
  workspaces: any[] = [];
  currentWsId: any;
  getWorkspace() {
    this.codegen.findWorkspaceByUser(this.securitySrv.userName).subscribe(body => {
      this.isLoading = false;
      if (body.status) {
        this.workspaces = body.data;
        if (this.workspaces && this.workspaces.length >= 1) {
          this.currentWsId = this.workspaces[0].id;
          this.queryNodeTree();
        }
      }
    });
  }

  queryNodeTree() {
    this.isLoading = true;
    this.nodeTree = [];
    this.codegen.queryFolderTree(this.currentWsId).subscribe(body => {
      this.isLoading = false;
      if (body.status) {
        this.nodeTree = body.data;
      }
    });
  }

  treeNodeDbClick(event: NzFormatEmitEvent): void {
    if (event.node?.origin['type'] == NodeType.table) {
      this.currentNodeData = event.node?.origin;
      this.queryTableInfo();
    }
  }

  nzParentNode: NzTreeNode | undefined | null;
  nzNode: NzTreeNode | undefined | null;

  treeNodeClick(event: NzFormatEmitEvent): void {
    this.nzNode = event.node;
    this.nzParentNode = event.node?.parentNode;
    if (this.nzNode?.origin['type'] == NodeType.table) {
      if (this.currentNodeData.key != this.nzNode?.key) {
        this.resetForm();
        this.tableInfoForm.controls.tableId.patchValue(this.nzNode?.key);
        this.tableInfoForm.controls.tableName.patchValue(this.nzNode?.title);
      }
    }
    this.currentNodeData = this.nzNode?.origin;
    this.currentPNodeData = this.nzParentNode?.origin;
  }

  cardIsLoading() {
    if ((this.currentNodeData.id != '' || this.currentNodeData.id != null) && this.currentNodeData.type === NodeType.table) {
      return false;
    }
    return true;
  }

  nzDropNode(event: NzFormatEmitEvent): void {
    // console.log(event);
    const drapNode: any = event.dragNode?.origin;
    const id = drapNode.id;
    const parentNode: any = event.dragNode?.parentNode?.origin;
    const pid = parentNode ? parentNode.id : 0;

    console.log(`id=${id}; pid=${pid}`);
    this.codegen.dropTree(id, pid).subscribe(body => {
      // console.log(JSON.stringify(body));
      if (body.status) {
        this.msgSrv.msg_success('保存成功');
        // this.queryMenuTree();
      } else {
        this.msgSrv.msg_warning(body.msg);
      }
    });
  }

  editedParentTitle: any;
  editedNodeTitle: any;
  addRootNode(tpl: TemplateRef<{}>): void {
    if (!this.currentWsId) {
      this.msgSrv.msg_warning('请选择工作空间');
      return;
    }
    this.editedParentTitle = '';
    this.editedNodeTitle = '';
    const newRootNode = this.newFolderNode();
    newRootNode.workspaceId = this.currentWsId;
    this.openNodeDialog('新增根节点', newRootNode, OptType.addRootNode, tpl);
  }

  addFolderNode(tpl: TemplateRef<{}>): void {
    if (this.nzTreeComponent.getSelectedNodeList().length <= 0) {
      this.msgSrv.msg_warning('请选择节点');
      return;
    }

    if (this.currentNodeData.type == NodeType.table) {
      this.msgSrv.msg_warning('该节点不能创建子节点');
      return;
    }

    const newNodeData = this.newFolderNode();
    newNodeData.workspaceId = this.currentWsId;
    newNodeData.pid = this.nzNode?.origin.key;
    this.editedParentTitle = this.nzNode?.origin.title;
    this.editedNodeTitle = this.editedParentTitle;

    this.openNodeDialog('新建子节点', newNodeData, OptType.addNode, tpl);
  }

  renameNode(tpl: TemplateRef<{}>): void {
    if (this.nzTreeComponent.getSelectedNodeList().length <= 0) {
      this.msgSrv.msg_warning('请选择节点');
      return;
    }

    this.editedParentTitle = this.nzNode?.origin.title;
    this.editedNodeTitle = this.editedParentTitle;

    // this.currentNodeData = this.this.newFolderNode();
    this.currentNodeData.workspaceId = this.currentWsId;
    this.openNodeDialog('重命名', this.currentNodeData, OptType.rename, tpl);
  }

  addTableNode(tpl: TemplateRef<{}>): void {
    if (this.nzTreeComponent.getSelectedNodeList().length <= 0) {
      this.msgSrv.msg_warning('请选择节点');
      return;
    }

    if (this.currentNodeData.type == NodeType.table) {
      this.msgSrv.msg_warning('该节点不能创建表');
      return;
    }

    const newTableNode = this.newFolderNode();
    newTableNode.workspaceId = this.currentWsId;

    newTableNode.pid = this.nzNode?.origin.key;
    newTableNode.type = NodeType.table;
    this.editedParentTitle = this.nzNode?.origin.title;
    this.editedNodeTitle = this.editedParentTitle;
    this.resetForm();
    this.openNodeDialog('新建表', newTableNode, OptType.addTable, tpl);
  }

  loading: Boolean = false;

  openNodeDialog(title: any, body: any, optType: string, tpl: TemplateRef<{}>): void {
    this.modalSrv.create({
      nzTitle: title,
      nzContent: tpl,
      nzOnOk: () => {
        this.loading = true;
        body.name = this.editedNodeTitle;
        body.title = this.editedNodeTitle;
        console.log(`request-${JSON.stringify(body)}`);
        this.codegen.saveFolderOrRename(body, optType).subscribe(res => {
          this.loading = false;
          console.log(res);
          if (res.status) {
            body.id = res.data;
            body.key = res.data as string;
            if (optType == OptType.addRootNode) {
              this.queryNodeTree();
            } else if (optType == OptType.rename) {
              this.tableInfoForm.controls.tableName.setValue(body.name);
            } else {
              if (optType == OptType.addTable) {
                // this.tableInfoForm.controls.tableId.patchValue(this.currentNodeData.id);
                // this.tableInfoForm.controls.folderId.patchValue(this.currentPNodeData.key);
                // this.tableInfoForm.controls.tableName.patchValue(this.currentNodeData.name);
              }
              const childrent: NzTreeNodeOptions[] = [body];
              this.nzNode?.addChildren(childrent);
            }

            this.cdr.detectChanges();
            this.msgSrv.msg_success(`保存成功`);
          } else {
            this.msgSrv.notice_warning('警告', `${res.msg}`);
          }
        });
      }
    });
  }

  deleteNode() {
    if (this.nzTreeComponent.getSelectedNodeList().length <= 0) {
      this.msgSrv.msg_warning('请选择节点');
      return;
    }

    if (this.nzTreeComponent.getSelectedNodeList()[0].getChildren().length >= 1) {
      this.msgSrv.msg_warning('请先删除子节点');
      return;
    }

    this.codegen.deleteNote(this.currentNodeData.id, this.nzNode?.origin['type']).subscribe(res => {
      if (res.status) {
        this.msgSrv.msg_success(`删除成功`);
        if (this.nzParentNode && this.nzParentNode?.getChildren().length >= 1) {
          this.nzNode?.remove();
        } else {
          this.queryNodeTree();
        }
      } else {
        this.msgSrv.notice_warning('警告', `${res.msg}`);
      }
    });
  }

  resetForm() {
    this.tableInfoForm.reset();
    this.tableInfoForm.controls.columns.clear();
    this.tableInfoForm.controls.constraints.clear();
  }

  tableInfoForm = new FormGroup({
    tableId: new FormControl(''),
    folderId: new FormControl('', { nonNullable: true, validators: [Validators.required] }),
    tableName: new FormControl('', { nonNullable: true, validators: [Validators.required] }),
    tableComment: new FormControl('', { nonNullable: true, validators: [Validators.required] }),
    sourceType: new FormControl(SourceType.input, { nonNullable: true, validators: [Validators.required] }),
    sourceName: new FormControl(''),
    sourceTable: new FormControl(''),
    remark: new FormControl(''),
    columns: new FormArray<FormGroup<ColumnForm>>([]),
    constraints: new FormArray<FormGroup<ConstraintForm>>([])
  });

  get columns(): FormArray<FormGroup<ColumnForm>> {
    return this.tableInfoForm.controls.columns;
  }
  get constraints(): FormArray<FormGroup<ConstraintForm>> {
    return this.tableInfoForm.controls.constraints;
  }
  getTableName() {
    return this.tableInfoForm.controls['tableName'].value;
  }

  columnIndex = -1;
  editColumnData = {};
  createColumnFormGroup(): FormGroup<ColumnForm> {
    return new FormGroup({
      columnName: new FormControl('', { nonNullable: true, validators: [Validators.required] }),
      columnComment: new FormControl('', { nonNullable: true, validators: [Validators.required] }),
      dataType: new FormControl('', { nonNullable: true, validators: [Validators.required] }),
      length: new FormControl('', { nonNullable: false, validators: [] }),
      scale: new FormControl('', { nonNullable: false, validators: [] }),
      nullable: new FormControl(true, { nonNullable: true, validators: [Validators.required] }),
      dataDefault: new FormControl('', { nonNullable: false, validators: [] })
    });
  }

  addColumn(): void {
    if (this.constraintIndex != -1) {
      this.msgSrv.msg_warning('请先完成约束的编辑');
      return;
    }

    const field = this.createColumnFormGroup();
    this.columns.push(field);
    this.editColumn(this.columns.length - 1);
  }

  addConstColumn(conType: any = 0, autoIncrement: any = false): void {
    if (this.constraintIndex != -1) {
      this.msgSrv.msg_warning('请先完成约束的编辑');
      return;
    }
    if (conType == 0) {
      if (this.isExistedByColumnName('id')) {
        this.msgSrv.msg_warning('id主键已存在, 可删除后再添加');
        return;
      }
      const field1 = this.createColumnFormGroup();
      this.columns.push(field1);
      field1.patchValue(CONST_COLUMNS.id);
      const field2 = this.createConstraintFormGroup();
      this.constraints.push(field2);
      field2.patchValue({
        constraintType: 'pk',
        constraintName: `pk0_${this.tableInfoForm.controls.tableName.value}`,
        columnList: ['id'],
        pkAutoIncrement: autoIncrement
      });
    } else if (conType == 1) {
      if (!this.isExistedByColumnName('created_by')) {
        const field1 = this.createColumnFormGroup();
        this.columns.push(field1);
        field1.patchValue(CONST_COLUMNS.createdBy);
      }

      if (!this.isExistedByColumnName('created_date')) {
        const field2 = this.createColumnFormGroup();
        this.columns.push(field2);
        field2.patchValue(CONST_COLUMNS.createdDate);
      }
    } else if (conType == 2) {
      if (!this.isExistedByColumnName('last_modified_by')) {
        const field1 = this.createColumnFormGroup();
        this.columns.push(field1);
        field1.patchValue(CONST_COLUMNS.lastModifiedBy);
      }
      if (!this.isExistedByColumnName('last_modified_date')) {
        const field2 = this.createColumnFormGroup();
        this.columns.push(field2);
        field2.patchValue(CONST_COLUMNS.lastModifiedDate);
      }
    }
  }

  delColumn(index: number): void {
    this.columns.removeAt(index);
  }

  editColumn(index: number): void {
    if (this.columnIndex !== -1 && this.editColumnData) {
      this.columns.at(this.columnIndex).patchValue(this.editColumnData);
    }
    this.editColumnData = { ...this.columns.at(index).value };
    this.columnIndex = index;
    // window.innerHeight
  }

  currentClasses = {
    display: 'block',
    overflow: 'auto',
    height: `${window.innerHeight - 150}px`
  };

  saveColumn(index: number): void {
    const item = this.columns.at(index);
    const itemData = item.getRawValue();

    if (DataTypes.indexOf(itemData.dataType) >= 0) {
      if (itemData['length'] == '' || itemData['length'] == null) {
        this.msgSrv.msg_warning(`${itemData.dataType} 需填写长度`);
        return;
      }
    }

    this.formValidity(item.controls);
    if (item.invalid) {
      this.msgSrv.msg_error('字段表单无效');
      return;
    }
    this.columnIndex = -1;
  }

  cancelColumn(index: number): void {
    const item = this.columns.at(index);
    if (!item.value.columnName) {
      this.delColumn(index);
    } else {
      item.patchValue(this.editColumnData);
    }
    this.columnIndex = -1;
  }

  clearColumn() {
    if (this.columnIndex != -1) {
      this.msgSrv.msg_warning('请优先完成字段编辑');
      return;
    }

    this.msgSrv.form_delete(
      '请确定是否真的要清空？',
      '清空请点击“确定”',
      () => {
        this.tableInfoForm.controls.columns.clear();
      },
      () => {}
    );
  }

  constraintIndex = -1;
  editConstraintData = {};
  // columnList 表单空间，直接写值[], 默认创建一个元素，则应该是bug，定义initColumn就没问题
  initColumn: any[] = [];
  createConstraintFormGroup(): FormGroup<ConstraintForm> {
    return new FormGroup({
      constraintType: new FormControl('', { nonNullable: true, validators: [Validators.required] }),
      constraintName: new FormControl('', { nonNullable: true, validators: [Validators.required] }),
      columnList: new FormControl(this.initColumn, { nonNullable: true, validators: [Validators.required] }),
      pkAutoIncrement: new FormControl(false, { nonNullable: true, validators: [Validators.required] })
    });
  }

  colNames: any[] = [];
  addConstraint(): void {
    if (this.columnIndex != -1) {
      this.msgSrv.msg_warning('请优先完成字段编辑');
      return;
    }
    if (this.columns.length <= 0) {
      this.msgSrv.msg_warning('请先完成字段的设计');
      return;
    }

    this.colNames = [];
    const columnsData: any[] = this.tableInfoForm.controls.columns.value;
    columnsData.map(col => {
      this.colNames.push(col.columnName);
    });

    const field = this.createConstraintFormGroup();
    this.constraints.push(field);
    this.editConstraint(this.constraints.length - 1);
  }

  delConstraint(index: number): void {
    this.constraints.removeAt(index);
  }

  editConstraint(index: number): void {
    if (this.constraintIndex !== -1 && this.editConstraintData) {
      this.constraints.at(this.constraintIndex).patchValue(this.editConstraintData);
    }
    this.editConstraintData = { ...this.constraints.at(index).value };
    this.constraintIndex = index;
  }

  saveConstraint(index: number): void {
    const item = this.constraints.at(index);
    this.formValidity(item.controls);
    if (item.invalid) {
      this.msgSrv.msg_error('约束表单无效');
      return;
    }
    this.constraintIndex = -1;
  }

  cancelConstraint(index: number): void {
    const item = this.constraints.at(index);
    if (!item.value.constraintName) {
      this.delConstraint(index);
    } else {
      item.patchValue(this.editConstraintData);
    }
    this.constraintIndex = -1;
  }

  clearConstraint() {
    if (this.constraintIndex != -1) {
      this.msgSrv.msg_warning('请优先完成约束编辑');
      return;
    }
    this.tableInfoForm.controls.constraints.clear();
  }

  constraintTypesChange(event: any, index: number) {
    const item = this.constraints.at(index);
    item.controls.constraintName.patchValue(`${event}${index}_${this.tableInfoForm.controls.tableName.value}`);
  }

  saveTableInfo(): void {
    if (!this.currentNodeData.id) {
      return;
    }

    this.formValidity(this.tableInfoForm.controls);
    // console.log(this.tableInfoForm.getRawValue());
    // console.log(this.tableInfoForm.getError(''));
    // console.log(this.tableInfoForm.invalid);

    // if (this.tableInfoForm.invalid) {
    //   this.msgSrv.msg_warning('表单无效');
    //   return;
    // }
    const body = {
      metaTable: {
        tableId: this.tableInfoForm.controls.tableId.value,
        folderId: this.tableInfoForm.controls.folderId.value,
        tableName: this.tableInfoForm.controls.tableName.value,
        tableComment: this.tableInfoForm.controls.tableComment.value,
        sourceType: this.tableInfoForm.controls.sourceType.value,
        sourceName: this.tableInfoForm.controls.sourceName.value,
        sourceTable: this.tableInfoForm.controls.sourceTable.value,
        remark: this.tableInfoForm.controls.remark.value
      },
      metaColumns: this.tableInfoForm.controls.columns.value,
      metaConstraints: this.tableInfoForm.controls.constraints.value
    };
    console.log(body);
    this.codegen.saveTableInfo(body).subscribe(res => {
      this.loading = false;
      if (res.status) {
        this.msgSrv.msg_success(`保存成功`);
      } else {
        this.msgSrv.notice_warning('警告', `${res.msg}`);
      }
    });
  }

  queryTableInfo() {
    if (!this.currentNodeData.id) {
      return;
    }
    this.codegen.queryTableInfo(this.currentNodeData.id).subscribe(res => {
      this.loading = false;
      if (res.status) {
        this.setFormData(res.data);
      } else {
        this.msgSrv.notice_warning('', `${res.msg}`);
      }
    });
  }

  setFormData(body: any) {
    // console.log(body);
    this.tableInfoForm.patchValue(body.metaTable);
    if (body.metaColumns && body.metaColumns.length >= 1) {
      this.tableInfoForm.controls.columns.clear();
      body.metaColumns.forEach((col: any) => {
        const field = this.createColumnFormGroup();
        field.patchValue(col);
        this.tableInfoForm.controls.columns.push(field);
      });
    }

    if (body.metaConstraints && body.metaConstraints.length >= 1) {
      this.tableInfoForm.controls.constraints.clear();
      body.metaConstraints.forEach((col: any) => {
        const field = this.createConstraintFormGroup();
        field.patchValue(col);
        this.tableInfoForm.controls.constraints.push(field);
      });
    }
  }

  updateColumnGrid(body: any) {
    console.log(body);
    if (body.metaColumns && body.metaColumns.length >= 1) {
      body.metaColumns.forEach((col: any) => {
        const field = this.createColumnFormGroup();
        field.patchValue(col);
        this.tableInfoForm.controls.columns.push(field);
      });
    }
  }

  deleteTableInfo(id: any) {
    this.codegen.deleteTableInfo(id).subscribe(res => {
      this.loading = false;
      if (res.status) {
        this.msgSrv.msg_success(`删除成功`);
        this.currentNodeData = this.newFolderNode();
        this.resetForm();
      } else {
        this.msgSrv.notice_warning('警告', `${res.msg}`);
      }
    });
  }

  private formValidity(controls: NzSafeAny): void {
    Object.keys(controls).forEach(key => {
      const control = (controls as NzSafeAny)[key] as AbstractControl;
      control.markAsDirty();
      control.updateValueAndValidity();
    });
  }

  drawerOption: any = {
    visible: false,
    title: '',
    size: 'large'
  };

  dbTypes: any[] = ['mysql', 'oracle', 'postgresql', 'sqlserver', 'maxcompute1', 'hologres', 'clickhouse', 'flink'];
  druidDbTypes: any[] = DruidDbTypes;
  dbType: any = '';

  drawerVisible: boolean = false;
  metaSql: any = '';

  currentType = -1;
  openDrawer(importTypeValue: any) {
    this.drawerOption.visible = true;
    if (this.currentType != importTypeValue) {
      this.currentType = importTypeValue;
      this.metaSql = '';
      this.drawerOption.title = `请填写${ImportType[this.currentType]}内容`;
    }
  }

  saveSqlDrawer() {
    if (this.currentType == ImportType.SQL) {
      this.codegen.importMetaParseSql(this.dbType, this.metaSql).subscribe(res => {
        if (res.status) {
          this.setFormData(res.data);
          this.msgSrv.msg_success(`导入成功`);
          this.drawerOption.visible = false;
        } else {
          this.msgSrv.notice_warning('警告', `${res.msg}`);
        }
      });
    } else if (this.currentType == ImportType.JSON) {
      this.codegen.importMetaParseJson(this.metaSql).subscribe(res => {
        if (res.status) {
          this.setFormData(res.data);
          this.msgSrv.msg_success(`导入成功`);
          this.drawerOption.visible = false;
        } else {
          this.msgSrv.notice_warning('警告', `${res.msg}`);
        }
      });
    }
  }
  closeSqlDrawer() {
    this.drawerOption.visible = false;
  }

  uploadRecord: ExcelUploadRecord = {
    currentQueueId: '',
    business: 'cg-metatable',
    title: '元数据表',
    showExtendedFields: false,
    action: 'save',
    sourceId: '1',
    extendedFields: 'unified',
    hintExtendedFields:
      '请填写数据库类型， 默认通用类型unified， 支持mysql, oracle, postgresql, maxcompute1, maxcompute2, clickhouse, flink',
    remark: ''
  };

  importExcelData() {
    this.uploadRecord.currentQueueId = 0;
    this.uploadRecord.sourceId = this.currentNodeData.id;
    this.uploadRecord.extendedFields = this.currentWsId;
    const record = this.uploadRecord as any;
    this.modal.create(ExcelUploadComponent, { record }, { size: 'md' }).subscribe(res => {
      if (res.status) {
        this.uploadRecord.currentQueueId = res.data;
        this.queryNodeTree();
      }
    });
  }

  downloadExcelTemplate() {
    this.cdr.detectChanges();
    try {
      this.excelSrv.downTemplateFile(this.uploadRecord);
    } finally {
      this.cdr.detectChanges();
    }
  }

  navUploadLogView() {
    this.excelSrv.navUploadLogView(this.uploadRecord);
  }

  selectTableFromDataBase() {
    let pid: any = this.nzNode?.origin['id'];
    this.modal.create(DataSourceSelectComponent, {}, { size: 'md' }).subscribe(res => {
      if (res.status) {
        this.codegen.importFromDataBase(res.data.selectedDataSource, res.data.selectedTable, pid, this.currentWsId).subscribe(res => {
          if (res.status) {
            this.queryNodeTree();
            this.msgSrv.msg_success('导入成功');
          } else {
            this.msgSrv.msg_error(`导入失败${res.msg}`);
          }
        });
      }
    });
  }

  isUpdateTableColumn() {
    const tableId = this.tableInfoForm.controls.tableId.value;
    const sourceType = this.tableInfoForm.controls.sourceType.value;
    return tableId && sourceType && sourceType == SourceType.database;
  }

  updateTableColumnFromDataBase() {
    if (!this.isUpdateTableColumn()) {
      this.msgSrv.msg_warning('来源类型必须数据库，并且请先保存后，才能更新字段');
      return;
    }
    const tableId = this.tableInfoForm.controls.tableId.value;
    const tableName = this.tableInfoForm.controls.sourceTable.value;
    const sourceName = this.tableInfoForm.controls.sourceName.value;
    this.codegen.updateColumnFromDataBase(sourceName, tableName, tableId).subscribe(res => {
      console.log('updateColumnFromDataBase', res);
      if (res.status) {
        this.updateColumnGrid(res.data);
        // this.queryNodeTree();
        this.msgSrv.msg_success('更新成功');
      } else {
        this.msgSrv.msg_error(`更新失败${res.msg}`);
      }
    });
  }

  selectTableId: any;
  newTableName: any;
  onTreeSelectChange($event: any): void {
    // this.selectTableId = $event;
    if (this.nzTreeSelect.getSelectedNodeList().length >= 1) {
      this.newTableName = `${this.nzTreeSelect.getSelectedNodeList()[0].title}_copy`;
    }
  }

  importFromMetaTable(tpl: TemplateRef<{}>): void {
    if (this.nzTreeComponent.getSelectedNodeList().length <= 0) {
      this.msgSrv.msg_warning('请选择节点');
      return;
    }

    if (this.currentNodeData.type == NodeType.table) {
      this.msgSrv.msg_warning('该节点不能创建表');
      return;
    }

    this.modalSrv.create({
      nzTitle: '克隆表',
      nzContent: tpl,
      nzOnOk: () => {
        this.loading = true;
        this.codegen
          .importFromMetaTable(this.newTableName, this.selectTableId, this.nzNode?.origin.key, this.currentWsId)
          .subscribe(res => {
            this.loading = false;
            if (res.status) {
              this.currentNodeData.id = res.data;
              this.currentNodeData.key = res.data;
              this.queryNodeTree();
              this.msgSrv.msg_success(`保存成功`);
            } else {
              this.msgSrv.notice_warning('警告', `${res.msg}`);
            }
          });
      }
    });
  }
  scriptDbType = 'mysql';
  namingRule = 'same';
  navigateDbScript() {
    if (this.currentNodeData.type == NodeType.folder) {
      this.msgSrv.msg_warning('请选择表节点');
      return;
    }
    if (!this.currentNodeData.id) {
      this.msgSrv.msg_warning('请选择表');
      return;
    }

    this.router.navigateByUrl(
      `/codegen/lang/db/script?actionType=${ActionType.edit}&sourceType=${LangSourceType.meta}&sourceName=${this.currentPNodeData.title}&sourceLabel=${this.currentNodeData.title}&sourceTable=${this.currentNodeData.id}&namingRule=${this.namingRule}&scriptDbType=${this.scriptDbType}`
    );
  }

  navigateJpaScript() {
    if (this.currentNodeData.type == NodeType.folder) {
      this.msgSrv.msg_warning('请选择表节点');
      return;
    }
    if (!this.currentNodeData.id) {
      this.msgSrv.msg_warning('请选择表');
      return;
    }

    this.router.navigateByUrl(
      `/codegen/lang/jpa/script?sourceType=${LangSourceType.meta}&sourceName=${this.currentPNodeData.title}&sourceLabel=${this.currentNodeData.title}&sourceTable=${this.currentNodeData.id}&namingRule=${this.namingRule}&scriptDbType=${this.scriptDbType}`
    );
  }

  openDbScript() {
    if (this.currentNodeData.type == NodeType.folder) {
      this.msgSrv.msg_warning('请选择表节点');
      return;
    }
    if (!this.currentNodeData.id) {
      this.msgSrv.msg_warning('请选择表');
      return;
    }

    const record: any = {
      actionType: ActionType.edit,
      sourceType: LangSourceType.meta,
      sourceName: this.currentPNodeData.title,
      sourceLabel: this.currentNodeData.title,
      sourceTable: this.currentNodeData.id,
      namingRule: this.namingRule,
      scriptDbType: this.scriptDbType
    };
    this.modal.create(LangDBScriptComponent, { record }, { size: 'xl' }).subscribe(res => {
      console.log(res);
    });
  }

  openJpaScript() {
    if (this.currentNodeData.type == NodeType.folder) {
      this.msgSrv.msg_warning('请选择表节点');
      return;
    }
    if (!this.currentNodeData.id) {
      this.msgSrv.msg_warning('请选择表');
      return;
    }

    const record: any = {
      sourceType: LangSourceType.meta,
      sourceName: this.currentPNodeData.title,
      sourceLabel: this.currentNodeData.title,
      sourceTable: this.currentNodeData.id,
      namingRule: this.namingRule,
      scriptDbType: this.scriptDbType
    };
    this.modal.create(LangJpaScriptComponent, { record }, { size: 'xl' }).subscribe(res => {
      console.log(res);
    });
  }

  treeContextMenu($event: MouseEvent, menu: NzDropdownMenuComponent): void {
    this.nzContextMenuService.create($event, menu);
  }

  sqlFormat() {
    this.metaSql = this.codegen.sqlformat(this.metaSql, this.dbType);
  }

  exportColumnTemplate() {
    const data = [
      ['字段英文名', '字段中文名', '数据类型', '长度', '刻度', '可空', '默认值'],
      ['字段英文名', '字段中文名', '数据类型', '长度', '刻度', '可空', '默认值']
    ];
    this.updownSrv.exportXlsx('xlsx', data, '表字段列表', `表上传模版.xlsx`);
  }

  exportColumnList() {
    let data = [['字段英文名', '字段中文名', '数据类型', '长度', '刻度', '可空', '默认值']];

    this.columns.controls.forEach(element => {
      const coldata = [
        element.controls.columnName.value as string,
        element.controls.columnComment.value as string,
        element.controls.dataType.value as string,
        element.controls.length.value as string,
        element.controls.scale.value as string,
        element.controls.nullable.value as any as string,
        element.controls.dataDefault.value as string
      ];
      data = [...data, coldata];
    });
    this.updownSrv.exportXlsx('xlsx', data, '字段列表', `${this.getTableName()}导出字段列表.xlsx`);
  }

  importColumnList(e: Event): void {
    if (this.constraintIndex != -1) {
      this.msgSrv.msg_warning('请先完成约束的编辑');
      return;
    }

    const node = e.target as HTMLInputElement;
    this.updownSrv.importXlsx(node.files![0]).then(res => {
      const keys = Object.keys(res);
      const values = res[keys[0]];
      if (values && values.length >= 2) {
        for (let index = 1; index < values.length; index++) {
          // console.log(values[index]);
          const cName = values[index][0] as any as string;
          if (this.isExistedByColumnName(cName)) {
            continue;
          }
          const colData = {
            columnName: cName,
            columnComment: values[index][1] as any as string,
            dataType: values[index][2] as any as string,
            length: values[index][3] as any as string,
            scale: values[index][4] as any as string,
            nullable: values[index][5] as any as boolean,
            dataDefault: values[index][6] as any as string
          };
          console.log(colData);

          const field = this.createColumnFormGroup();
          this.columns.push(field);
          field.patchValue(colData);
        }
        this.cdr.detectChanges();
      }
    });
    node.value = '';
  }

  isExistedByColumnName(cName: any) {
    for (let index = 0; index < this.columns.controls.length; index++) {
      const element = this.columns.controls[index];
      const columnName = element.controls.columnName.value as string;
      if (columnName === cName) {
        return true;
      }
    }
    return false;
  }
  searchTreeValue = '';

  metaTableType = 'current';
  metaTableId: any;
  importFromMetaColumn(tpl: TemplateRef<{}>): void {
    if (!this.currentNodeData.id) {
      this.msgSrv.msg_warning('请先创建表或加载表');
      return;
    }

    if (this.columns.length >= 1) {
      this.metaTableType = 'current';
      this.metaRows = this.columns.getRawValue();
    } else {
      this.metaTableType = 'other';
    }

    this.selectedMetaColumn = [];
    this.modalSrv.create({
      nzTitle: '克隆字段',
      nzStyle: { width: '850px' },
      nzContent: tpl,
      nzOnOk: () => {
        this.loading = true;
        if (this.selectedMetaColumn && this.selectedMetaColumn.length >= 1) {
          if (this.metaTableType === 'other') {
            for (let index = 0; index < this.selectedMetaColumn.length; index++) {
              const cName = this.selectedMetaColumn[index]['columnName'];
              if (this.isExistedByColumnName(cName)) {
                continue;
              }
              const field = this.createColumnFormGroup();
              this.columns.push(field);
              field.patchValue(this.selectedMetaColumn[index]);
            }
          } else {
            for (let index = 0; index < this.selectedMetaColumn.length; index++) {
              const cName = this.selectedMetaColumn[index]['columnName'];
              this.selectedMetaColumn[index]['columnName'] = `${cName}1`;
              console.log(this.selectedMetaColumn[index]);
              const field = this.createColumnFormGroup();
              this.columns.push(field);
              field.patchValue(this.selectedMetaColumn[index]);
            }
          }
        }
      }
    });
  }

  metaRows: any[] = [];
  @ViewChild('st', { static: false }) st!: STComponent;
  metaColumn: STColumn[] = [
    { title: '选择', index: 'selected', type: 'checkbox' },
    { title: '英文名', index: 'columnName' },
    { title: '中文名', index: 'columnComment' },
    { title: '数据类型', index: 'dataType' },
    { title: '长度', index: 'length' },
    { title: '刻度', index: 'scapt' },
    { title: '默认值', index: 'dataDefault' }
  ];

  onMetaTableTypeChange(value: any): void {
    if (value === 'current') {
      this.metaRows = this.columns.getRawValue();
    } else {
      this.metaTableId = '';
      this.metaRows = [];
    }
  }

  metaLoading = false;
  onMetaTreeSelectChange(value: any): void {
    // console.log(value);
    if (value) {
      this.metaLoading = true;
      this.metaRows = [];
      this.codegen.getColumnInfo(value).subscribe(res => {
        if (res.status) {
          this.metaRows = res.data;
        }
        this.metaLoading = false;
        this.cdr.detectChanges();
      });
    }
  }

  selectedMetaColumn: any[] | undefined = [];
  onMetaSTChange(e: STChange): void {
    if (e!.type === 'checkbox') {
      this.selectedMetaColumn = e.checkbox;
    }
  }
}
